var mongoose = require('mongoose'),
    config = require("../config"),
    Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId,
    debug = require("debug")("consultant:models");
var _ = require('underscore');
var settings = require('../config');
var async = require('async');
require('date-utils');
//connett mongodb
mongoose.connect(config.db_url);

/*
* 咨询师申请
* */
var UserDoctor = new Schema({
    wcopenid: String,
    username: String,
    mobilephone: String,
    email: String,
    about: String,
    fordate: Date,
    state : {type: Number, default: 0}  //0未审核1已审核
});
UserDoctor.index({
    wcopenid: 1
});
var userDoctor = mongoose.model("UserDoctor", UserDoctor);

userDoctor.prototype.saveUser = function (callback) {
    this.save(function (err) {
        debug("this err",err);
        callback(err);
    });
}
/*
* 根据openid查询医师信息
* */
userDoctor.prototype.findUserByOpenid = function (opneid, callback) {
    userDoctor.findOne({
        "wcopenid": opneid
    }, function (err, doc) {
        callback(err, doc);
    });
}

/*
 *微信用户
 */
var UserSchema = new Schema({
    wcopenid: String,
    nickname: String,
    weight: {
        type: Number,
        max: 1000
    },
    user_group: String,
    count: { //咨询次数
        type: Number,
        max: 50
    },
    headimgurl:String,
    random: Number,
    createtime:Date
});
UserSchema.index({
    wcopenid: 1
});
var User = mongoose.model("User", UserSchema);

User.prototype.saveUser = function (callback) {
    this.save(function (err) {
        callback(err);
    });
}
/**
 * 根据user_group，openid查找群组内的用户
 *
 */
User.prototype.findopenidBygroup = function (openid,callback) {
    User.find({user_group:"80"},function(err,datas){
        if(datas.length==0){
            var data=0;
            return callback(err,data);
        }else{
            for(var i=0;i<datas.length;i++){
                if(datas[i].wcopenid==openid){
                    var data=1;
                    return callback(err,data);
                }
            }
            var data=0;
            return callback(err,data);
        }
    })
}
/**
 *
 * @param fromOpneid
 * @param callback
 * return 返回wcopenid的数组
 */
User.prototype.findTopUser = function (fromOpneid, callback) {
    async.waterfall([function (cb) {
        //排除已经建立会话的咨询师
        new WCSession().findSessionStatusIsOne(function (err, sessions) {
            var ninopenids_session = [];
            if (sessions.length > 0) {
                _.each(sessions, function (session, index, list) {
                    if (session.receive_openid) ninopenids_session.push(session.receive_openid);//20150306 已建立会话的咨询师
                    //if (session.send_openid) ninopenids_session.push(session.send_openid);
                });
            }
            cb(err, ninopenids_session);
        })
        }, function(ninopenids_session,cb){//200150306

        /*new SignIn().findSignInsByDate(ninopenids_session,fromOpneid, function(err, signIns){//查询签到了的用户且排除已建立会话的咨询师
            var userOnline = [];
            if(signIns.length > 0){
                _.each(signIns, function (signIn, index, list) {
                    //userOnline.push(signIn.wcopenid);
                    userOnline.push(signIn._id);
                });
            }
            cb(err, userOnline);
        });*///200150306 去掉签到功能所以用不到
       // cb(ninopenids_session);//200150306

        var query = User.find({
            user_group: 101,//20150306
            wcopenid: {
                $ne: fromOpneid//$ne:!=
            }
        });

        query.sort({
            weight: -1
        });
        query.where("wcopenid").nin(//排除建立会话的
            ninopenids_session//userOnline
        );
        query.exec(function (err, users) {
            debug('get weight user', users);
            var openids_session = [];
            if (users.length > 0) {
                _.each(users, function (user, index, list) {
                    if (user.wcopenid) openids_session.push(user.wcopenid);
                })
            }
            cb(err, openids_session);
        });

    }, function (openids_session, cb) {//function (userOnline, cb) {//20150306改为从咨询师中抽取用户
        //根据权重获取指定数量一半的咨询师
        var query = User.find({
            user_group: 101,//20150306
            wcopenid: {
                $ne: fromOpneid//$ne:!=
            }
        });
        //根据发送比例从签到用户中得到发送人数的一半
        var userOnlineCount = openids_session.length;//userOnline.length;
        var limit = Math.ceil((userOnlineCount*settings.userProportion)/2);//发送比例再除以2
        //var limit = Math.ceil(settings.receiver / 2);//返回大于等于x的最小整数
        query.limit(limit);
        query.sort({
            weight: -1
        });
        query.where("wcopenid").in(//从签到且未建立会话的所有用户中取出权重高发送人数的一半的用户
            openids_session//userOnline
        );
        query.exec(function (err, users) {
            debug('get weight user', users);
            var userlist_weight = [];
            if (users.length > 0) {
                _.each(users, function (user, index, list) {
                    if (user.wcopenid) userlist_weight.push(user.wcopenid);
                })
            }
            var others = _.difference(openids_session,userlist_weight);//(userOnline,userlist_weight);//另一半已签到的
            //cb(err, userlist_weight, signIns);
            cb(err, others,userlist_weight,userOnlineCount);
        });
    }, function (others, userlist_weight,userOnlineCount, cb) {
        //随机抽取指定数量一半的咨询师
        //不在查询范围内的咨询师
        var random = Math.random();
        /*getRandomUser(userlist_weight, ninopenids_session, {$gte: random}, fromOpneid, function (err, userlist_random) {
            if (userlist_random) {
                var userlist = _.union(userlist_weight, userlist_random);
                cb(err, userlist);
            } else {
                getRandomUser(userlist_weight, ninopenids_session, {$lt: random}, fromOpneid, function (err, userlist_random) {
                    var userlist = _.union(userlist_weight, userlist_random);
                    cb(err, userlist);
                })
            }
        });*/
        var userCount = Math.ceil((userOnlineCount*settings.userProportion)/2);//计算可收到消息的用户数
        if(userOnlineCount>1){//用户大于一个人执行 另一半用户随机获取
            getRandomUser(others,userOnlineCount, {$gte: random}, fromOpneid, function (err, userlist_random) {
                if (userlist_random) {
                    var userlist = _.union(userlist_weight, userlist_random);
                    cb(err, userlist,userCount);
                } else {
                    getRandomUser(others,userOnlineCount, {$lt: random}, fromOpneid, function (err, userlist_random) {
                        var userlist = _.union(userlist_weight, userlist_random);
                        cb(err, userlist, userCount);
                    })
                }
            });
        }else{
            cb(null, userlist_weight, userCount);
        }

    }], function (err, result, userCount) {
            debug("get the top user ", result);
        callback(err, result, userCount);
    });
}
/**
 *
 * @param userlist_weight 获取权重排名的用户
 * @param ninopenids_session 排除正在接诊的用户
 * @param crandom random字段的查询条件
 * @param fromOpneid 发信息用户openid
 * @param callback
 * return 返回userlist_random随机咨询师名单
 *//*function getRandomUser(userlist_weight, ninopenids_session, crandom, fromOpneid, callback) {*/
function getRandomUser(others, userOnlineCount, crandom, fromOpneid, callback) {
    //var ninopenids_all = _.union(userlist_weight, ninopenids_session);
    var query = User.find({
        user_group: 101,//20150306
        wcopenid: {
            $ne: fromOpneid
        },
        random: crandom
    });
    query.sort({weight: -1});
    var limit = Math.floor(userOnlineCount*settings.userProportion / 2);
    query.where("wcopenid").in(
        others
    );
    query.limit(limit);
    query.exec(function (err, users) {
        debug('get random user', users);
        var userlist_random = [];
        if (users.length > 0) {
            _.each(users, function (user, index, list) {
                if (user.wcopenid) userlist_random.push(user.wcopenid);
            })
        }
        callback(err, userlist_random);
    });
}
User.prototype.findUserByOpenid = function (opneid, callback) {
    User.findOne({
        "wcopenid": opneid
    }, function (err, doc) {
        callback(err, doc);
    })
}
User.prototype.findHtmlUserByOpenid = function (opneid, callback) {
    User.findOne({
        "wcopenid": opneid,
        "user_group":"80"
    }, function (err, doc) {
        callback(err, doc);
    })
}
/**
 * 根据_ID查询用户信息
 * @param callback
 */
User.prototype.findUserById = function (uid, callback) {
    User.findOne({
        "_id": uid
    }, function (err, doc) {
        callback(err, doc);
    })
}
User.prototype.updateHtmlUserByOpneId = function (opneid, options, callback) {
    User.update({
            "wcopenid": opneid,
            "user_group":"80"
        }, {
            $set: options
        },
        function (err) {
            callback(err);
        })
}

User.prototype.removeAllUser = function (callback) {
    User.remove({}, function (err) {
        callback(err);
    })
}
/**
 *咨询次数消费--1
 */
User.prototype.updateUserCountByOpneId = function (opneid, callback) {
    User.update({
        "wcopenid": opneid
    }, {
        "$inc": {
            "count": -1
        }
    }, function (err) {
        callback(err);
    })
}
/**
 *购买咨询次数
 */
User.prototype.updateUserCountByOpneIdBuy = function (opneid, count, callback) {
    User.update({
        "wcopenid": opneid
    }, {
        "$inc": {
            "count": count
        }
    }, function (err) {
        callback(err);
    })
}
/**
 *用户同步方法
 */
User.prototype.updateUserByOpneId = function (opneid, options, callback) {
    User.update({
            "wcopenid": opneid
        }, {
            $set: options
        },
        function (err) {
            callback(err);
        })
}
User.prototype.updateUserWeightByOpenId = function (condition, incoptions, callback) {
    User.update(condition, {
        $inc: incoptions
    }, function (err) {
        callback(err);
    })
}
/*
 *微信消息
 */
var MessageSchema = new Schema({
    send_openid: String,//发送者ID
    receive_openid: String,//接收者ID
    sendcontent: String,//消息内容
    msgid: String,
    msgtype: String,//消息类型
    date: String,//时间
    wcsessionid: ObjectId,//会话的session id
    messageinfo: {},//微信接口返回的消息对象
    room:String
});

MessageSchema.index({
    send_openid: 1,
    date: -1
});
var Message = mongoose.model("Message", MessageSchema);

Message.prototype.saveMessage = function (message, callback) {
    message.save(function (err) {
        callback(err);
    })
}

/**
 *根据sendopenid查询sessionid
 */
/*Message.prototype.findSessionsBysid1 = function (openid,num,snum, callback) {
console.log(num+" "+snum);

        if(num!=0){
            Message.aggregate()
                .match({"send_openid":openid})
                .group({ _id: '$wcsessionid'})
                .project({ _id:1})
                .limit(Number(num))
                .exec(function (err, res) {
//                  console.log(res);
                    callback(err, res);
                });
        }
        if(snum!=0){
            Message.aggregate()
                .match({"send_openid":openid})
                .group({ _id: '$wcsessionid'})
                .project({ _id:1})
                .skip(Number(snum))
                .exec(function (err, res) {
//                  console.log(res);
                    callback(err, res);
                });
        }
}*/

/**
 * 关键字查询对话记录
 */
Message.prototype.findMessagesByKeywords = function(keywords,num,snum, callback) {
   /* Message.find({"sendcontent":new RegExp(keywords)},function(err,docs){
        callback(err,docs);
    });*/

    Message.aggregate()
        .match({"sendcontent":new RegExp(keywords),"room":{$exists:false}})
        .group({ _id: '$wcsessionid'})
        .project({ _id:1})
        .skip(Number(snum))
        .limit(Number(num))
        .exec(function (err, res) {
//            console.log(res);
            callback(err, res);
        });
}

/**
 * html版 关键字查询对话记录
 */
Message.prototype.findMessagesByKeywordsandRoom = function(keywords,room,num,snum, callback) {
    /* Message.find({"sendcontent":new RegExp(keywords)},function(err,docs){
     callback(err,docs);
     });*/

    Message.aggregate()
        .match({"sendcontent":new RegExp(keywords),"room":room})
        .group({ _id: '$wcsessionid'})
        .project({ _id:1})
        .skip(Number(snum))
        .limit(Number(num))
        .exec(function (err, res) {
//            console.log(res);
            callback(err, res);
        });
}

/**
 * 查询关键词的单条记录
 */
Message.prototype.findMessageBySidandContent = function (sessionid,keywords, callback) {
    Message.findOne({"wcsessionid":sessionid,"sendcontent":new RegExp(keywords)},function(err,docs){
        callback(err,docs);
    });
};

/*
*
* 查询此sessionid下的对话记录数*/
Message.prototype.countMsgBysid = function (sessionid, callback) {

    Message.aggregate()
        .match({"wcsessionid":sessionid})
        .group({ _id: '$send_openid',count:{$sum:1}})
        .project({ _id:1,count:1})
        .exec(function (err, res) {
//            console.log(res);
            callback(err, res);
        });

}

/*
* 查询某一会话中所有对话记录*/
Message.prototype.findMessagesBysid = function (sessionid,islimit, callback) {
    var query = Message.find({
            'wcsessionid':sessionid
        });
    if(islimit){
        query.limit(10);
    }
    query.sort({//时间从小到大
        date: 'asc'
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}
/**
 * html版查询同一sessionid下的所有聊天记录
 */
Message.prototype.getChatDetail = function (sessionid, callback){
    var query = Message.find({
        'wcsessionid':sessionid
    });
    query.sort({
        date: 'asc'
    });
    query.exec(function (err, docs) {
        callback(err,docs);
    });
}

/*
 *微信会话
 */
var SessionSchema = new Schema({
    send_openid: String,
    receive_openid: String,
    status: Number, //0-->会话已发起,1-->会话已建立,2-->会话已结束
    start_date: Date,//会话发起时间
    build_date: Date,//会话建立时间
    relet_date: Date,//接诊时，续时要修改这个时间，也是timer
    relet_count: {
        type: Number,
        default: 0
    },
    notify_count: {
        type: Number,
        default: 0
    }, //0-->代表未通知
    comment: {
        type: Number,
        default: 0//0代表未进行评价的会话
    },
    stat: {type: Number, default: 0},//0代表评价未统计;1代表评价已统计;2代表结算已统计
    public_chat:{type: Number, default: 0},//对话公开，默认不公开，公开为1
    chargeback:{type: Number, default: 0},//不扣费为1
    firstTime: {//记录是否是第一次提问
        type: Number,
        default: 0//0代表第一次提问
    },
    room:String
});
SessionSchema.index({
    send_openid: 1,
    status: 1
});

SessionSchema.index({
    receive_openid: 1,
    status: 1
});

var WCSession = mongoose.model("WCSession", SessionSchema);

WCSession.prototype.saveWCSession = function (callback) {
    this.save(function (err) {
        callback(err);
    })
}
WCSession.prototype.addWCSession = function (callback) {
    this.save(function (doc) {
        callback(doc);
    })
}
/**
 * 根据room查找此群组内status>=0并且<=1的数据
 *
 */
WCSession.prototype.findStatusByRoom=function(room,callback){
    WCSession.find({room:room,status:{"$in":[0,1]}},function(err,datas){
        return callback(datas);
    });
}
/**
 * 根据openid和room查询数据
 *
 */
WCSession.prototype.findByOpenidandRoom=function(openid,room,callback){
    var query = WCSession.find({send_openid:openid,room:room});

//    query.skip(Number(snum));
//    query.limit(Number(num));
    query.sort({
        "start_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}
/**
 * html5版 会话结束 修改status状态为2
 *
 */
WCSession.prototype.updateStatusByOpneIdandRoom = function (sendopenid,room, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "room":room,
        "status": {
            $lte: 1
        }
    }, {
        $set: {
            "status": 2 //会话结束
        }
    }, function (err) {
        if (err) {
            debug("updateSessionBySessionId error!!", err);
        }
        callback(err);
    });
}
/**
 * 根据send_openid,查询到_id
 */
WCSession.prototype.findSessionidByOpenid = function(sendopenid,room,callback) {
    WCSession.find({
        "send_openid":sendopenid,
        room:room
    },function(err,docs){
        callback(err,docs);
    });
}
/**
 *根据openid查找send_openid或receive_openid两个字段中有一个相等的并且status为会话已经建立
 *
 */
WCSession.prototype.findSessionByOpenId = function (condition, openid, callback) {
    var query = WCSession.find(condition);
    query.or([
        {
            "send_openid": openid
        },
        {
            "receive_openid": openid
        }
    ]);
    query.sort({
        "build_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}


/**
 *根据openid查找send_openid或receive_openid两个字段中有一个相等的并且status为会话已经建立
 *
 */
WCSession.prototype.findSessionsBysid = function (openid,num,snum, callback) {
    var query = WCSession.find(
        {
            "receive_openid":{$ne:null},
            "$or":[{"send_openid":openid},{"receive_openid":openid}],
            "status":{"$gt":1},
            "room":{$exists:false}

        });

    query.skip(Number(snum));
    query.limit(Number(num));
    query.sort({
        "build_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}

/**
 * 查询单条sesson
 */
WCSession.prototype.finSessionBysid = function(sid, callback) {
    WCSession.find({
        "_id":sid
    },function(err,docs){
        callback(err,docs);
    });
}

/**
 * 查询此次会话的续费次数
 * @param sid
 * @param callback
 */
WCSession.prototype.findReletCountBySid = function(sid,callback){
    WCSession.findOne({
        "_id":sid
    },{
        "relet_count":1,
        send_openid: 1,
        receive_openid: 1,
        "_id":0
    },function(err,docs){
        callback(err,docs);
    });
}
/**
 * 查询已经被公开的会话的前num条
 */
WCSession.prototype.findSessionByPubChat = function(num,snum,callback){
    var query = WCSession.find({
            "public_chat":{"$gt":0},
            "room":{$exists:false}
        });
    query.skip(Number(snum));
    query.limit(Number(num));
    query.sort({
        "build_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}

//html版查询会话前num条
WCSession.prototype.findSessionByPubChatandRoom = function(room,num,snum,callback){
    var query = WCSession.find({
        "public_chat":{"$gt":0},
        "room":room
    });
    query.skip(Number(snum));
    query.limit(Number(num));
    query.sort({
        "build_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}

/**
 *查询所有状态为1的会话
 */
WCSession.prototype.findSessionByStatus = function (status, callback) {
    var query = WCSession.find({
        status: status
    });
    query.sort({
        "start_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}
/**
 *根据sendopenid查找staus为0的会话
 *可能存在用户未等到咨询师回复再发一次消息的情况，系统为其创建了两次会话，谁要抢到此单修改两个会话的状态。
 */
WCSession.prototype.findSessionBySendOpenId = function (sendopenid, callback) {
    var query = WCSession.find({
        "send_openid": sendopenid,
        "status": 0
    });
    query.sort({
        "start_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}

/*
 *根据receiveopenid查找status为1的会话
 */
WCSession.prototype.findSessionStatusIsOne = function (callback) {
    var query = WCSession.find({
        status: 1
    }, {
        "receive_openid": 1,
        "send_openid":1,
        "_id": 0
    });
    query.sort({
        "start_date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}
WCSession.prototype.findSessionCommon = function (condition, callback) {
    var query = WCSession.find(condition)
    query.exec(function (err, result) {
        callback(err, result);
    })
}
/**
 * 超时提醒
 * @param sendopenid
 * @param callback
 */
WCSession.prototype.updateSessionNotifyByOpendId = function (sendopenid, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "status": 1
    }, {
        "$inc": {
            "notify_count": 1
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionBySessionId error!!", err);
        }
        callback(err);
    });
}
/**
 * html版超时提醒
 * @param sendopenid
 * @param callback
 */
WCSession.prototype.updateSessionNotifyByOpendIdandRoom = function (sendopenid,room,callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "room":room,
        "status": 1
    }, {
        "$inc": {
            "notify_count": 1
        }
    }, function (err) {
        if (err) {
            debug("updateSessionBySessionId error!!", err);
        }
        callback(err);
    });
}
/**
 *对话公开
 */
WCSession.prototype.updateSessionPublicChat = function (sessionid,public_chat,callback){
    WCSession.update({
        "_id":sessionid
    },{
        "$set":{
            "public_chat":public_chat
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionPublicChat error!!", err);
        }
        callback(err);
    });
}

/**
 * 设置不扣费
 */
WCSession.prototype.updateChargeback = function (sessionid,callback) {
    WCSession.update({
        "_id":sessionid
    },{
        "$inc":{
            "chargeback":1
        }
    }, function (err) {
        if (err) {
            debug("updateChargeback error!!", err);
        }
        callback(err);
    });
}

/**
 *
 * @param sendopenid 会话发起者openid
 * @param receiveopenid 会话接受者openid
 * @param callback
 */
WCSession.prototype.updateSessionBySendOpneId = function (sendopenid, receiveopenid, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "status": 0
    }, {
        $set: {
            "status": 1, //会话建立
            "receive_openid": receiveopenid,
            "build_date": new Date()
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionBySendOpneId error!!", err);
        }
        callback(err);
    });
}
WCSession.prototype.updateStatusByOpneId = function (sendopenid, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "status": 0
    }, {
        $set: {
            "status": 1, //会话建立
            "build_date": new Date()
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionBySendOpneId error!!", err);
        }
        callback(err);
    });
}
/**
 *根据send_opneid结束会话
 *如果是用户或咨询师主动点击结束会话，直接将用户发起的status=0的会话一并结束。
 */
WCSession.prototype.updateSessionBySendOpneId2 = function (sendopenid, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "status": {
            $lte: 1
        }
    }, {
        $set: {
            "status": 2 //会话结束
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionBySessionId error!!", err);
        }
        callback(err);
    });
}
/**
 *根据receive_openid结束会话
 *如果是用户或咨询师主动点击结束会话，直接将用户发起的status=0的会话一并结束。
 */
WCSession.prototype.updateSessionByReceiveOpneId = function (receiveopenid, callback) {
    WCSession.update({
        "receive_openid": receiveopenid,
        "status": {
            $lte: 1
        }
    }, {
        $set: {
            "status": 2 //会话结束
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionByReceiveOpneId error!!", err);
        }
        callback(err);
    });
}
/**
 * 用户续租时执行
 * @param sendopenid
 * @param callback
 */
WCSession.prototype.updateSessionReletByOpenId = function (sendopenid, recevieopenid, status, callback) {
    WCSession.update({
        "send_openid": sendopenid,
        "receive_openid": recevieopenid,
        "status": status
    }, {
        $set: {
            "relet_date": new Date().addMinutes(settings.notifytime / 60)//续租时间
        },
        "$inc": {
            "relet_count": 1
        },
        $set: {//只要续时就设置firsttime为1，续时过的都标记为需要扣费
            "firstTime": 1
        }
    }, {
        multi: true
    }, function (err) {
        if (err) {
            debug("updateSessionReletByOpenId error!!", err);
        }
        callback(err);
    });
}
/**
 *
 * @param condition 查询条件
 * @param setoptions 更新对象
 * @param multi 是否更新多条
 * @param callback 回掉函数
 */
WCSession.prototype.updateSessionCommon = function (condition, setoptions, multi, callback) {
    WCSession.update(
        condition
        , {
            $set: setoptions
        }, {
            multi: multi
        }, function (err) {
            if (err) {
                debug("updateSessionCommon error!!", err);
            }
            callback(err);
        }
    );
}
/**
 *按照咨询师分组进行统计
 * @param condition 查询条件
 * @param callback  回调函数
 */
WCSession.prototype.findSessionGroupBy = function (condition, callback) {
    //count这里用了$sum:1实现http://docs.mongodb.org/manual/reference/operator/aggregation/group/
    WCSession.aggregate()
        .match(condition)
        .group({ _id: '$receive_openid', sumComment: { $sum: '$comment' }, count: { $sum: 1 } })
        .project({ _id: 1, sumComment: 1, count: 1 })
        .exec(function (err, res) {
//            console.log(res);
            callback(err, res);
        });
}

/**
 * 根据openid和会话状态（1）查询会话sessionid
 */
WCSession.prototype.findSessionIdByStatus = function (sendopenid, status, callback) {
    var query = WCSession.find(
        {
            "$or":[{"send_openid":sendopenid},{"receive_openid":sendopenid}],
            "status":{"$lt":2}
        });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}

/*
* 查询receive_openid
* */
WCSession.prototype.findRididBySid = function (sid, callback) {
    WCSession.findOne(
        {
            "_id" : sid
        },{

            "receive_openid" : 1,
            "send_openid" : 1,
            "public_chat" : 1,
            "_id" : 0
        },function (err, docs) {
        callback(err, docs);
    });
}


/**
 *存储微信token
 */
var tokenSchema = new Schema({
    id: String,
    token: String,
    expireTime: String,
    refreshToken: String,
    date: Date
});
var Token = mongoose.model("Token", tokenSchema);
Token.prototype.saveToken = function (accesstoken, callback) {
    accesstoken.save(function (err) {
        callback(err);
        debug("add new token", err);
    })
}
Token.prototype.findTokenById = function (tid, callback) {
    Token.findOne({
        id: tid
    }, function (err, token) {
        debug("find token by id", token);
        callback(err, token);
    });
}
Token.prototype.removeTokenById = function (id, callback) {
    Token.remove({
        "id": id
    }, function (err, docs) {
        debug("delete token", JSON.stringify(docs));
        callback(err);
    })
}
/**
 *更新OAuth
 */
// Token.prototype.updateToken = function(token, callback) {
// 	Token.update({
// 		"id": token.id
// 	}, {
// 		"token": token.token,
// 		"expireTime": token.expireTime,
// 		"refreshToken": token.refreshToken
// 	}, function(err, numberaffected) {
// 		callback(err, numberaffected);
// 	})
// }
/**
 *更新token含oauth123和token123
 */
Token.prototype.updateTokenById = function (id, options, callback) {
    Token.update({
        "id": id
    }, {
        $set: options
    }, function (err, numberaffected) {
        callback(err, numberaffected);
    })
}
/**
 *商品
 */
var GoodSchema = new Schema({
    name: String,
    price: {
        type: Number,
        max: 1000
    },
    servicecount: Number,
    sales: Number,
    discount: Number,
    describe: String
})
var Good = mongoose.model("Good", GoodSchema);
Good.prototype.saveGood = function (good, callback) {
    good.save(function (err, product, numberaffected) {
        callback(err);
    })
}
Good.prototype.findGoods = function (callback) {
    Good.find(function (err, goods) {
        callback(err, goods);
    })
}
Good.prototype.findGoodById = function (id, callback) {
    Good.findOne({
        "_id": id
    }, function (err, good) {
        callback(err, good);
    })
}
/**
 *订单
 */
var OrderSchema = new Schema({
    price: Number,
    status: Number, //0代表未支付，1代表已支付
    date: String,
    goodname: String,
    servicecount: Number,
    tradeno: String,
    openid: String
})
var Order = mongoose.model("Order", OrderSchema);
Order.prototype.saveOrder = function (order, callback) {
    order.save(function (err, product, numberaffected) {
        callback(err);
    })
}
Order.prototype.updateOrderStatusByTradeno = function (tradeno, callback) {
    Order.update({
            "tradeno": tradeno
        }, {
            "status": 1
        },
        function (err, numberaffected) {
            callback(err, numberaffected);
        })
};
Order.prototype.updateOrderOpneIdByTradeno = function (tradeno, openid, callback) {
    Order.update({
            "tradeno": tradeno
        }, {
            "status": 1,
            "openid": openid
        },
        function (err, numberaffected, raw) {
            callback(err, numberaffected, raw);
        })
}
Order.prototype.findOrderByOpenId = function (openid, callback) {
    var query = Order.find({
        "openid": openid
    });
    query.sort({
        "date": -1
    });
    query.exec(function (err, docs) {
        callback(err, docs);
    });
}
Order.prototype.findOrderByTradeno = function (tradeno, callback) {
    Order.findOne({
        "tradeno": tradeno
    }, function (err, order) {
        callback(err, order);
    })
}
/**
 *签到
 */
var SignInSchema = new Schema({
    wcopenid: String,
    signState: String,
    date: Date
})
var SignIn = mongoose.model("SignIn", SignInSchema);

SignIn.prototype.saveSignIn = function (signin, callback) {
    signin.save(function (err) {
        if(err){
            callback(err);
        }else{
            new User().updateUserCountByOpneIdBuy(signin.wcopenid,1,function(err){//每次签到咨询次数加一
                callback(err);
            });
        }
    })
}
SignIn.prototype.findSignInByDate = function (openid, date, callback) {
    SignIn.findOne({
        "wcopenid": openid,
        "date": {
            "$gte": new Date(date)
        }
    }, function (err, signin) {
        callback(err, signin);
    });
};

SignIn.prototype.findSignInsByDate = function (ninopenids_session,fromOpneid, callback) {
    /*var query = SignIn.find({
        "date": {
            "$gte":  new Date()-60*60*1000*48
        }
    });
    query.where("wcopenid").nin(//排除已经建立会话的用户
        ninopenids_session
    );
    query.exec(function (err, signins) {
        callback(err, signins);
    });*/
    SignIn.aggregate()
        .match({
            /*wcopenid: {
                $ne: fromOpneid//$ne:!=
            },*/
            signState : "online",
            date : {
                $gte : new Date(new Date()-60*60*1000*48)//48小时内的签到人数
            },
            wcopenid : {
                $nin : ninopenids_session,
                $ne: fromOpneid
            }
        })
        .group({ _id: '$wcopenid'})
        .project({ _id:1})
        .exec(function (err, res) {
            callback(err, res);
        });
/*
    Message.aggregate()
        .match({"sendcontent":new RegExp(keywords)})
        .group({ _id: '$wcsessionid'})
        .project({ _id:1})
        .skip(Number(snum))
        .limit(Number(num))
        .exec(function (err, res) {
//            console.log(res);
            callback(err, res);
        });*/
}

/**
 * 更新用户在线状态
 */
SignIn.prototype.updateSignIn = function(openid, date, status, callback) {
    SignIn.update({
        "wcopenid": openid,
        "date": {
            "$gte": new Date(new Date()-60*60*1000*48)//把时间改为48小时内，更新所有签到记录，避免签退后再次接到消息
        }
    },{
        "signState" : status
    },{
        multi: true
    },function(err){
        callback(err);
    });
}

/**
 * 结算单
 */
var PayOffSchema = new Schema({
    payoff_count: Number,
    income: Number,
    payoff_totalcount: Number,
    payoff_date: Date,
    wcopenid: String,
    nickname: String,
    pay: {
        type: Number,
        default: 0
    }//0未付款，1已付款
})
var PayOff = mongoose.model('PayOff', PayOffSchema);
/**
 * 存储结算单
 * @param callback 回调函数
 */
PayOff.prototype.savePayoff = function (callback) {
    this.save(function (err) {
        callback(err);
    })
}
PayOff.prototype.findPayoff = function (condition, callback) {
    var query = PayOff.find(condition);
    query.sort(
        {payoff_date: -1}
    )
    query.exec(function (err, result) {
        callback(err, result);
    })
}

/**
 * 用户查看全部公开记录的付款记录
 */
var PubChatPaySchema = new Schema({
    //wcsessionid : String,
    openid : String,//被扣费用户openid
    count : Number,//要扣除此用户的咨询次数
    status : Number,//
    send_openid : String,//咨询者id
    receive_openid : String,//咨询师io
    allocation : Number,//咨询者得到的分成
    receiveAllocation : Number,//咨询师得到的分成
    wcsessionid : String,
    date : Date
});
var PubChatPay = mongoose.model('PubChatPay', PubChatPaySchema);
/**
 * 存储付款记录
 */
PubChatPay.prototype.savePubChatPay = function(callback){
    this.save(function(err){
       callback(err);
    });
}
PubChatPay.prototype.findPubChatPayByIds = function(openid,sid,callback){
    PubChatPay.findOne({
        openid:openid,
        wcsessionid:sid
    },function(err,docs){
        callback(err,docs);
    });
}
PubChatPay.prototype.findPubChatPayById = function (condition, callback) {
    var query = PubChatPay.find(condition)
    query.exec(function (err, result) {
        callback(err, result);
    })
}

var MUserSchema = new Schema({
    user_name: String,
    user_passwd: String,
    phone:String,
    email:String,
    user_type: Number, //0默认商户，管理订单等 1代表管理员，定制微信账号
    appID:String,//应用ID
    appSecret:String,//应用密钥
    appStatus:Number,
    createtime:Date

});
var MUser = mongoose.model("musers", MUserSchema);
MUser.prototype.findMUser = function (condition, callback) {
    MUser.findOne(condition, function (err, user) {
        callback(err, user);
    })
}

module.exports.MUser = MUser;
module.exports.UserDoctor = userDoctor;
module.exports.User = User;
module.exports.Message = Message;
module.exports.Token = Token;
module.exports.WCSession = WCSession;
module.exports.Good = Good;
module.exports.Order = Order;
module.exports.SignIn = SignIn;
module.exports.PayOff = PayOff;
module.exports.PubChatPay = PubChatPay;